;; core/routine.scm - (c) rohan drape, 2002-2005

;; A simple co-routine constructor, built using call/cc.  `z' is a
;; procedure of two arguments.  The first is an initial input, the
;; second a procedure of one argument that is used to 'yield' a value.
;; Yielding returns the value to the initiator of the routine, and
;; pauses the routine at the current location until it is initiated
;; again.  Returns a dispatch procedure, the methods are 'next' and
;; 'reset'.

(define-structure routine (step undo))

(defineV (make-routine z)
  (let* ((a #f)
	 (b #f)
	 (goto-a (lambda (result)
		   (call/cc (lambda (exit)
			      (set! b exit)
			      (if (not a)
				  (error "routine: goto-a: a not set?")
				  (a result))))))
	 (goto-b (lambda (input)
		   (call/cc (lambda (exit)
			      (set! a exit)
			      (if b
				  (b input)
				  (z input goto-a))))))
	 (undo (lambda () (set! a #f) (set! b #f))))
    (make-routine* goto-b undo)))

(define (routine-next r value)
  ((routine-step r) value))

(define (routine-reset r)
  ((routine-undo r)))

		     
